#ifndef __UTILS_H__
#define __UTILS_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <sys/time.h>
#include <stdint.h>
#include "log.h"


#define MUTEX_LOCK(lock, CODE)	\
	pthread_mutex_lock(&lock);  do { CODE; } while (0); pthread_mutex_unlock(&lock);
	
#define safe_freep(p)	if (p) { free(p); p = NULL; }


//extern int64_t now_time;

static inline int64_t sys_gettime(void)
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (int64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
static inline uint32_t sys_gettime32(void)
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (uint32_t)tv.tv_sec * 1000 + (uint32_t)tv.tv_usec / 1000;
}


static int sys_strftime(char* buf, const char* fmt, int64_t time_ms)
{
	// static const char* fmt_chars = "YMDhmsN";
	struct tm* lt;
	time_t st;
	char* p = buf;
	
	st = (time_t)(time_ms / 1000);
	lt = localtime(&st);
	
	while (*fmt) {
		if (*fmt == '%') {
			char ch = *(fmt + 1);
			switch (ch) {
				case 'Y':
					p += sprintf(p, "%d", lt->tm_year + 1900);
					ch = 0;
					break;
				case 'M':
					p += sprintf(p, "%02d", lt->tm_mon + 1);
					ch = 0;
					break;
				case 'D':
					p += sprintf(p, "%02d", lt->tm_mday);
					ch = 0;
					break;
				case 'h':
					p += sprintf(p, "%02d", lt->tm_hour);
					ch = 0;
					break;
				case 'm':
					p += sprintf(p, "%02d", lt->tm_min);
					ch = 0;
					break;
				case 's':
					p += sprintf(p, "%02d", lt->tm_sec);
					ch = 0;
					break;
				case 'N':
					p += sprintf(p, "%-3d", (int)(time_ms % 1000));
					ch = 0;
					break;
			}
			if (!ch) {
				fmt += 2;
				continue;
			}
		}

		*p++ = *fmt++;
	}
	*p = 0;
	return p - buf;
}

static inline int str_safecpy(char* dst, const char* src, size_t n)
{
	char *p, *pe;
	if (!dst || !src)
		return 0;

	p = dst;
	pe = dst + (n - 1);
	while (p < pe && *src) *p++ = *src++;
	*p = 0;
	return p - dst;
}


static inline char* to_hexstring(uint8_t* data, int length)
{
    static char buf[255];
    char* p = buf;
    int i;
    if (length > 48)
        length = 48;
    
    for (i = 0; i < length; i++) {
        if (p != buf)
            *p++ = ' ';
        p += sprintf(p, "%02x", data[i]);
    }
    *p = 0;
    return buf;
}
#ifdef __cplusplus
}
#endif

#endif
